package com.gec.anan.payment.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.gec.anan.common.constant.MqConst;
import com.gec.anan.common.execption.AnanException;
import com.gec.anan.common.result.ResultCodeEnum;
import com.gec.anan.common.service.RabbitService;
import com.gec.anan.driver.client.DriverAccountFeignClient;
import com.gec.anan.model.entity.payment.PaymentInfo;
import com.gec.anan.model.enums.TradeType;
import com.gec.anan.model.form.driver.TransferForm;
import com.gec.anan.model.form.payment.PaymentInfoForm;
import com.gec.anan.model.vo.order.OrderRewardVo;
import com.gec.anan.model.vo.payment.WxPrepayVo;
import com.gec.anan.order.client.OrderInfoFeignClient;
import com.gec.anan.payment.config.WxPayV3Properties;
import com.gec.anan.payment.mapper.PaymentInfoMapper;
import com.gec.anan.payment.service.WxPayService;
import com.wechat.pay.java.core.exception.ServiceException;
import com.wechat.pay.java.service.payments.model.Transaction;
import io.seata.spring.annotation.GlobalTransactional;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;

@Service
@Slf4j
public class WxPayServiceImpl implements WxPayService {

    @Autowired
    private PaymentInfoMapper paymentInfoMapper;

//    @Autowired
//    private RSAAutoCertificateConfig rsaAutoCertificateConfig;
    @Autowired
    private WxPayV3Properties wxPayV3Properties;

    @Autowired
    private RabbitService rabbitService;
    @Autowired
    private OrderInfoFeignClient orderInfoFeignClient;
    @Autowired
    private DriverAccountFeignClient driverAccountFeignClient;


    //创建微信支付
    @Override
    public WxPrepayVo createWxPayment(PaymentInfoForm paymentInfoForm) {
        try {
            //1 添加支付记录到表
            //判断是否存在订单，存在就不用添加
            LambdaQueryWrapper<PaymentInfo> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(PaymentInfo::getOrderNo, paymentInfoForm.getOrderNo());
            PaymentInfo paymentInfo = paymentInfoMapper.selectOne(queryWrapper);
            if (paymentInfo == null) {
                paymentInfo = new PaymentInfo();
                BeanUtils.copyProperties(paymentInfoForm, paymentInfo);
                paymentInfo.setPaymentStatus(0);
                paymentInfoMapper.insert(paymentInfo);
            }
            //2 创建微信支付对象
//            JsapiServiceExtension serviceExtension = new JsapiServiceExtension
//                    .Builder().config(rsaAutoCertificateConfig).build();
//            //3 封装request请求对象参数
//            PrepayRequest request = new PrepayRequest();
//            Amount amount = new Amount();
//
//            // amount.setTotal(paymentInfoForm.getAmount().intValue());按照指定金额支付
//            amount.setTotal(1); //测试使用
//            request.setAmount(amount);
//            request.setAppid(wxPayV3Properties.getAppid());
//            request.setMchid(wxPayV3Properties.getMerchantId());
//            String description = paymentInfo.getContent();
//            if (description.length() > 127) {
//                description = description.substring(0, 127);
//            }
//            request.setDescription(description);
//            request.setNotifyUrl(wxPayV3Properties.getNotifyUrl());
//            request.setOutTradeNo(paymentInfo.getOrderNo());
//
//            //获取用户信息
//            Payer payer = new Payer();
//            payer.setOpenid(paymentInfoForm.getCustomerOpenId());
//            request.setPayer(payer);
//
//            //是否指定分账，不指定不能分账
//            SettleInfo settleInfo = new SettleInfo();
//            settleInfo.setProfitSharing(true);
//            request.setSettleInfo(settleInfo);
//            //4 调用微信支付接口
//            PrepayWithRequestPaymentResponse response = serviceExtension.prepayWithRequestPayment(request);
//            5 封装返回对象
            WxPrepayVo wxPrepayVo = new WxPrepayVo();
            wxPrepayVo.setPaySign("abc123def456ghi789");
            wxPrepayVo.setSignType("ALIPAY");
            wxPrepayVo.setAppId(paymentInfo.getCustomerOpenId());
            wxPrepayVo.setNonceStr("");
            wxPrepayVo.setPackageVal("预支付请求成功");
            wxPrepayVo.setTimeStamp(String.valueOf(System.currentTimeMillis() / 1000));
            //个人测试
            Transaction transaction = new Transaction();
            transaction.setOutTradeNo(paymentInfo.getOrderNo());
            transaction.setTransactionId(paymentInfo.getTransactionId());
            handlePayment(transaction);
            return wxPrepayVo;
        } catch (Exception e) {
            e.printStackTrace();
            throw new AnanException(ResultCodeEnum.DATA_ERROR);
        }
    }

    //支付结果查询
    @Override
    public Boolean queryPayStatus(String orderNo) {
        //创建一个微信服务对象
//        JsapiServiceExtension serviceExtension = new JsapiServiceExtension
//                .Builder().config(rsaAutoCertificateConfig).build();
        //封装查询支付状态需要参数
//        QueryOrderByOutTradeNoRequest queryRequest = new QueryOrderByOutTradeNoRequest();
//        queryRequest.setMchid(wxPayV3Properties.getMerchantId());
//        queryRequest.setOutTradeNo(orderNo);
        try {
            //调用微信查询接口 实现查询
            //Transaction transaction = serviceExtension.queryOrderByOutTradeNo(queryRequest);
            //返回结果判断
//            if (transaction != null &&
//                    transaction.getTradeState() == Transaction.TradeStateEnum.SUCCESS) {
//                //成功执行操作
//                handlePayment(transaction);
//                return true;
//            }
            //测试修改
            Transaction transaction = new Transaction();
            transaction.setOutTradeNo(orderNo);
            //成功执行操作
            handlePayment(transaction);
            return true;
        } catch (ServiceException e) {
            // API返回失败, 例如ORDER_NOT_EXISTS
            System.out.printf("code=[%s], message=[%s]\n", e.getErrorCode(), e.getErrorMessage());
        }
        return false;
    }

//    @Transactional
//    @Override
//    public void wxnotify(HttpServletRequest request) {
//        //1.回调通知的验签与解密
//        //从request头信息获取参数
//        //HTTP 头 Wechatpay-Signature
//        // HTTP 头 Wechatpay-Nonce
//        //HTTP 头 Wechatpay-Timestamp
//        //HTTP 头 Wechatpay-Serial
//        //HTTP 头 Wechatpay-Signature-Type
//        //HTTP 请求体 body。切记使用原始报文，不要用 JSON 对象序列化后的字符串，避免验签的 body 和原文不一致。
////        String wechatPaySerial = request.getHeader("Wechatpay-Serial");
////        String nonce = request.getHeader("Wechatpay-Nonce");
////        String timestamp = request.getHeader("Wechatpay-Timestamp");
////        String signature = request.getHeader("Wechatpay-Signature");
////        String requestBody = RequestUtils.readData(request);
////        log.info("wechatPaySerial：{}", wechatPaySerial);
////        log.info("nonce：{}", nonce);
////        log.info("timestamp：{}", timestamp);
////        log.info("signature：{}", signature);
////        log.info("requestBody：{}", requestBody);
////
////        //2.构造 RequestParam
////        RequestParam requestParam = new RequestParam.Builder()
////                .serialNumber(wechatPaySerial)
////                .nonce(nonce)
////                .signature(signature)
////                .timestamp(timestamp)
////                .body(requestBody)
////                .build();
////
////
////        //3.初始化 NotificationParser
////        NotificationParser parser = new NotificationParser(rsaAutoCertificateConfig);
////        //4.以支付通知回调为例，验签、解密并转换成 Transaction
////        Transaction transaction = parser.parse(requestParam, Transaction.class);
////        log.info("成功解析：{}", JSON.toJSONString(transaction));
////        if (null != transaction && transaction.getTradeState() == Transaction.TradeStateEnum.SUCCESS) {
////            //5.处理支付业务
////            this.handlePayment(transaction);
////        }
//        Transaction transaction = new Transaction();
//        this.handlePayment(transaction);
//    }

    //处理支付成功的订单状态修改
    @Override
    @GlobalTransactional
    public void handleOrder(String orderNo) {
      //远程调用实现订单状态修改 已支付
       orderInfoFeignClient.updateOrderPayStatus(orderNo);
      //远程调用实现系统奖励
         //获取系统奖励
        OrderRewardVo orderRewardVo = orderInfoFeignClient.getOrderRewardFee(orderNo).getData();
        if (orderRewardVo != null && orderRewardVo.getRewardFee().doubleValue()>0) {
            //远程调用实现系统奖励
            TransferForm transferForm = new TransferForm();
            transferForm.setTradeNo(orderNo);
            transferForm.setTradeType(TradeType.REWARD.getType());
            transferForm.setContent(TradeType.REWARD.getContent());
            transferForm.setAmount(orderRewardVo.getRewardFee());
            transferForm.setDriverId(orderRewardVo.getDriverId());
            driverAccountFeignClient.transfer(transferForm);
        }
        //TODO 其他
    }

    //支付成功的操作
    public void handlePayment(Transaction transaction) {
        PaymentInfo paymentInfo = paymentInfoMapper
                .selectOne(new LambdaQueryWrapper<PaymentInfo>()
                        .eq(PaymentInfo::getOrderNo, transaction.getOutTradeNo()));
        if (paymentInfo.getPaymentStatus() == 1) {
            log.info("进入这里来");
            return;
        }

        //更新支付信息
        paymentInfo.setPaymentStatus(1);
        paymentInfo.setOrderNo(transaction.getOutTradeNo());
        paymentInfo.setTransactionId(transaction.getTransactionId());
        paymentInfo.setCallbackTime(new Date());
        paymentInfo.setCallbackContent(JSON.toJSONString(transaction));
        paymentInfoMapper.updateById(paymentInfo);
        // 表示交易成功！
         log.info("支付成功，调用队列MQ");
        // 后续更新订单状态！ 使用消息队列！
        rabbitService.sendMessage(MqConst.EXCHANGE_ORDER, MqConst.ROUTING_PAY_SUCCESS, paymentInfo.getOrderNo());
    }
}
